<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.7: http://docutils.sourceforge.net/" />
<title>Trestle JSON support</title>
<style type="text/css">

/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:Date: $Date: 2005-12-18 01:56:14 +0100 (Sun, 18 Dec 2005) $
:Revision: $Revision: 4224 $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

body { 
  font-family: verdana, arial, sans-serif;
  font-size: small;
  padding-right: 5em;
 }

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

dl.docutils dt {
  font-weight: bold }

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left {
  clear: left }

img.align-right {
  clear: right }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic ;
  color: #aaa;
  margin-top: -6px;
  padding-top: 0px;
  margin-left: 2em;
  font-size: smaller;
}

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em ;
  background-color: #eeeeee }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

tt.docutils {
  background-color: #eeeeee }

ul.auto-toc {
  list-style-type: none }

pre.response.pass, .pass
{ 
  background: #dfd; !important
 }

pre.response.fail, .fail
{ 
  background: #faa; !important
}

li.fail
{ 
  background: #fff;
}

li.fail a
{ 
  color: #f55;
  font-weight: bold;
}

tt.request.method
{ 
  font-weight: bold;
}

.contents
{ 
  float: right;
  font-size: smaller;
  border: 1px solid #ddd;
  padding-left: 1em;
  padding-right: 1em;
}

.contents ul
{ 
  padding-left: 1em;
  margin-right: .5em;
  margin-left: 0;
}

.contents p.topic-title
{ 
  padding-top: 1ex;
}

</style>
</head>
<body>
<div class="document" id="trestle-json-support">
<h1 class="title">Trestle JSON support</h1>

<p>If <a class="reference external" href="http://pypi.python.org/pypi/simplejson">simplejson</a> is installed, Trestle uses a special output checker for output
that claims to be json data. When Trestle sees a response with the content
type &quot;application/json&quot;, the json checker is automatically activated and used
in place of the normal output checker.</p>
<p>In the examples below, the full responses are:</p>
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/list</tt>
</pre>
<p class="caption">a list</p>
<pre class="response pass literal-block">
[1, 2, 3, &quot;a cow&quot;, &quot;a monkey&quot;, [2, 5, 6], &quot;the end&quot;]
</pre>
<!--  -->
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/dict</tt>
</pre>
<p class="caption">a dict</p>
<pre class="response pass literal-block">
{&quot;a&quot;: 1, &quot;b&quot;: &quot;hello&quot;, &quot;another&quot;: [5, 1, 9], &quot;sub&quot;: {&quot;key&quot;: &quot;value&quot;}}
</pre>
<!--  -->
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/string</tt>
</pre>
<p class="caption">a string</p>
<pre class="response pass literal-block">
&quot;The quick brown dog jumped over the lazy fox. Again.&quot;
</pre>
<!--  -->
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/number</tt>
</pre>
<p class="caption">a number</p>
<pre class="response pass literal-block">
1293039483
</pre>
<!--  -->
<p>When using the json output checker, a variety of wildcard-like
features are supported.</p>
<div class="section" id="any">
<h1>&lt;any&gt;</h1>
<p>The special construct &lt;any&gt; may be used as a list term or dict key or
value. In a list, it matches one or more terms.</p>
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/list</tt>
</pre>
<p class="caption">a list</p>
<pre class="response pass literal-block">
[1, 2, 3, &quot;a cow&quot;, &quot;a monkey&quot;, [2, 5, 6], &quot;the end&quot;]
</pre>
<!--  -->
<pre class="response pass literal-block">
[&lt;any&gt;]
</pre>
<!--  -->
<pre class="response pass literal-block">
[1, 2, 3, &lt;any&gt;]
</pre>
<!--  -->
<pre class="response pass literal-block">
[&lt;any&gt;, &quot;the end&quot;]
</pre>
<!--  -->
<pre class="response pass literal-block">
[&lt;any&gt;, &quot;a cow&quot;, &lt;any&gt;]
</pre>
<!--  -->
<p>In a dict, when used as a key <strong>and value</strong>, it matches one or more keys.</p>
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/dict</tt>
</pre>
<p class="caption">a dict</p>
<pre class="response pass literal-block">
{&quot;a&quot;: 1, &quot;b&quot;: &quot;hello&quot;, &quot;another&quot;: [5, 1, 9], &quot;sub&quot;: {&quot;key&quot;: &quot;value&quot;}}
</pre>
<!--  -->
<pre class="response pass literal-block">
{&quot;a&quot;: 1, &lt;any&gt;: &lt;any&gt;}
</pre>
<!--  -->
</div>
<div class="section" id="timestamp">
<h1>&lt;timestamp&gt;</h1>
<p>A timestamp wildcard matches strings of 6 or more contiguous digits.</p>
<pre class="literal-block">
<tt class="request method docutils literal">GET</tt> <tt class="request url docutils literal">/number</tt>
</pre>
<p class="caption">a timestamp-like number</p>
<pre class="response pass literal-block">
&lt;timestamp&gt;
</pre>
<!--  -->
<div class="section" id="source">
<h2>Source</h2>
<p>This document was built from the following .rst document:</p>
<pre class="literal-block">
Trestle JSON support
--------------------

.. fixtures:: about_json

If simplejson_ is installed, Trestle uses a special output checker for output
that claims to be json data. When Trestle sees a response with the content
type &quot;application/json&quot;, the json checker is automatically activated and used
in place of the normal output checker.

In the examples below, the full responses are:

.. request:: a list

   GET /list
..

.. response::

   [1, 2, 3, &quot;a cow&quot;, &quot;a monkey&quot;, [2, 5, 6], &quot;the end&quot;]
..

.. request:: a dict
   
   GET /dict
..

.. response::

   {&quot;a&quot;: 1, &quot;b&quot;: &quot;hello&quot;, &quot;another&quot;: [5, 1, 9], &quot;sub&quot;: {&quot;key&quot;: &quot;value&quot;}} 
..

.. request:: a string

   GET /string
..

.. response::

   &quot;The quick brown dog jumped over the lazy fox. Again.&quot;
..

.. request:: a number

   GET /number
..

.. response::

   1293039483
..

When using the json output checker, a variety of wildcard-like
features are supported.

&lt;any&gt;
~~~~~

The special construct &lt;any&gt; may be used as a list term or dict key or
value. In a list, it matches one or more terms.

.. request:: a list

   GET /list
..

.. response::

   [1, 2, 3, &quot;a cow&quot;, &quot;a monkey&quot;, [2, 5, 6], &quot;the end&quot;]
..

.. response::
  
   [&lt;any&gt;]
..

.. response::

  [1, 2, 3, &lt;any&gt;]
..

.. response::
  
   [&lt;any&gt;, &quot;the end&quot;]
..

.. response::

   [&lt;any&gt;, &quot;a cow&quot;, &lt;any&gt;]
..


In a dict, when used as a key **and value**, it matches one or more keys.

.. request:: a dict

   GET /dict
..

.. response::

   {&quot;a&quot;: 1, &quot;b&quot;: &quot;hello&quot;, &quot;another&quot;: [5, 1, 9], &quot;sub&quot;: {&quot;key&quot;: &quot;value&quot;}} 
..

.. response::

   {&quot;a&quot;: 1, &lt;any&gt;: &lt;any&gt;}
..


&lt;timestamp&gt;
~~~~~~~~~~~

A timestamp wildcard matches strings of 6 or more contiguous digits.

.. request:: a timestamp-like number

   GET /number
..

.. response::

   &lt;timestamp&gt;
..


Source
^^^^^^

This document was built from the following .rst document:

.. include:: json.rst
   :literal:

Using this fixture module:

.. include:: about_json.py
   :literal:
   
.. _`simplejson` : http://pypi.python.org/pypi/simplejson

</pre>
<p>Using this fixture module:</p>
<pre class="literal-block">
from cgi import parse_qsl
try:
    from json import dumps
except ImportError:
    from simplejson import dumps

from paste.fixture import TestApp

from trestle._json import odict


LIST = [1, 2, 3, &quot;a cow&quot;, &quot;a monkey&quot;, [2, 5, 6], &quot;the end&quot;]
DICT = odict(
    [(&quot;a&quot;, 1), (&quot;b&quot;, &quot;hello&quot;), (&quot;another&quot;, [5, 1, 9]),
     (&quot;sub&quot;, {&quot;key&quot;: &quot;value&quot;})])
STRING = &quot;The quick brown dog jumped over the lazy fox. Again.&quot;
NUMBER = 1293039483


def app(environ, start_response):
    start_response('200 Ok', [('Content-type', 'application/json')])

    thing = environ['PATH_INFO'][1:].upper()

    if environ['REQUEST_METHOD'] == 'GET':        
        return [dumps(globals()[thing])]
    elif environ['REQUEST_METHOD'] == 'POST':
        post_data = str(environ['wsgi.input'].read())
        params = parse_qsl(post_data)
        return ['You said: ', 
                ' and '.join('%s=%s' % p for p in params)]

def setup_all(cls):
    pass

def teardown_all(cls):
    pass

def setup_each(inst):
    pass

def teardown_each(inst):
    pass


client = TestApp(app)

</pre>
</div>
</div>
</div>
</body>
</html>
